<template>
  <div class="dashboard-container">
    <div id="anchor"></div>
    <div class="app-container">
      <el-card shadow="never">
        <div slot="header" class="clearfix">
          <span>{{
            this.$route.query.id ? $t("question.edit") : $t("question.add")
          }}</span>
        </div>
        <el-form
          :model="pubForm"
          :rules="pubRules"
          :key="key"
          ref="pubRef"
          label-width="140px"
        >
          <!-- 学科 -->
          <el-form-item :label="$t('table.subject') + ':'" prop="subjectID">
            <el-select
              v-model="pubForm.subjectID"
              @change="subjectChange"
              style="width: 50%;"
            >
              <el-option
                v-for="item in subjectList"
                :key="item.id"
                :label="item.subjectName"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <!-- 目录 -->
          <el-form-item :label="$t('table.directory') + ':'" prop="catalogID">
            <el-select v-model="pubForm.catalogID" style="width: 50%;">
              <el-option
                v-for="item in catalogList"
                :key="item.id"
                :label="item.directoryName"
                :value="item.id"
              ></el-option>
            </el-select>
          </el-form-item>

          <!-- 企业 -->
          <el-form-item
            :label="$t('question.enterprise') + ':'"
            prop="enterpriseID"
          >
            <el-select v-model="pubForm.enterpriseID" style="width: 50%;">
              <el-option
                v-for="item in companyList"
                :key="item.id"
                :label="item.shortName"
                :value="item.id"
              ></el-option>
            </el-select>
          </el-form-item>

          <!-- 城市 -->
          <el-form-item :label="$t('question.city') + ':'" prop="city">
            <el-select
              v-model="pubForm.province"
              style="width:24.8%"
              @change="provinceChange"
            >
              <el-option
                v-for="item in provinceList"
                :key="item.id"
                :label="item"
                :value="item"
              >
              </el-option>
            </el-select>
            <el-select
              v-model="pubForm.city"
              style="margin-left:5px;width:24.6%"
            >
              <el-option
                v-for="item in regionList"
                :key="item.id"
                :label="item"
                :value="item"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <!-- 方向 -->
          <el-form-item
            :label="$t('question.direction') + ':'"
            prop="direction"
          >
            <el-select v-model="pubForm.direction" style="width: 50%;">
              <el-option
                v-for="item in directionList"
                :key="item.id"
                :label="item"
                :value="item"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <!-- 题型 -->
          <el-form-item
            :label="$t('table.questionType') + ':'"
            prop="questionType"
          >
            <el-radio-group
              v-model="pubForm.questionType"
              @change="questionTypeChange"
            >
              <el-radio label="1">{{ $t("question.singleChoice") }}</el-radio>
              <el-radio label="2">{{ $t("question.multipleChoice") }}</el-radio>
              <el-radio label="3">{{ $t("question.shortAnswer") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 难度 -->
          <el-form-item :label="$t('table.difficulty') + ':'" prop="difficulty">
            <el-radio-group v-model="pubForm.difficulty">
              <el-radio label="1">{{ $t("question.simple") }}</el-radio>
              <el-radio label="2">{{ $t("question.ordinary") }}</el-radio>
              <el-radio label="3">{{ $t("question.hard") }}</el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 题干 富文本编辑器-->
          <el-form-item :label="$t('table.questionStem') + ':'" prop="question">
            <!-- 使用 v-model 进行双向的数据绑定 -->
            <quill-editor
              v-model="pubForm.question"
              ref="quillEditorQuestion"
              :options="quillOptionQuestion"
              @change="questionQuillChange"
              class="richText"
            ></quill-editor>
          </el-form-item>
          <!-- 富文本编辑器图片上传组件，隐藏 -->
          <el-upload
            action="#"
            id="uploaderQuestion"
            v-show="false"
            :http-request="uploadQuestion"
            :before-upload="beforeAvatarUpload"
          >
          </el-upload>
          <!-- 选项 -->
          <!-- 当且仅当题型数据等于字符串1或2时，方才显示选项部分 -->
          <el-form-item
            :label="$t('table.subject') + ':'"
            v-if="pubForm.questionType === '1' || pubForm.questionType === '2'"
          >
            <!-- 单选 -->
            <el-radio-group
              v-if="pubForm.questionType === '1'"
              v-model="radio"
              @change="radioChange"
            >
              <div class="erect" v-for="op in pubForm.options" :key="op.code">
                <el-radio :label="op.code">{{ op.code }}:</el-radio>
                <el-input v-model="op.title" class="erectInput"> </el-input>
                <el-upload
                  class="avatar-uploader"
                  action="https://jsonplaceholder.typicode.com/posts/"
                  :show-file-list="false"
                  :on-success="handleAvatarSuccess"
                  :before-upload="beforeAvatarUpload"
                >
                  <img v-if="op.img" :src="op.img" class="avatar" />
                  <i class="upload-icon">{{ $t("form.upload") }}</i>
                  <i class="el-icon-circle-close"></i>
                </el-upload>
              </div>
            </el-radio-group>
            <!-- 多选 -->
            <el-checkbox-group
              v-if="pubForm.questionType === '2'"
              v-model="checkList"
              :min="2"
              @change="checkboxChange"
            >
              <div class="erect" v-for="op in pubForm.options" :key="op.code">
                <el-checkbox :label="op.code">{{ op.code }}:</el-checkbox>
                <el-input v-model="op.title" class="erectInput"> </el-input>
                <el-upload
                  class="avatar-uploader"
                  action="https://jsonplaceholder.typicode.com/posts/"
                  :show-file-list="false"
                  :on-success="handleAvatarSuccess"
                  :before-upload="beforeAvatarUpload"
                >
                  <img v-if="op.img" :src="op.img" class="avatar" />
                  <i class="upload-icon">{{ $t("form.upload") }}</i>
                  <i class="el-icon-circle-close"></i>
                </el-upload>
              </div>
            </el-checkbox-group>
            <!-- 增加选项与答案，单选题禁用 -->
            <el-button
              type="danger"
              size="small"
              :disabled="pubForm.questionType === '1'"
              class="erectButton"
              @click="addOption"
              >+ {{ $t("form.addOption") }}</el-button
            >
          </el-form-item>

          <!-- 解析视频 -->
          <el-form-item :label="$t('question.video') + ':'" prop="videoURL">
            <el-input v-model="pubForm.videoURL" style="width: 50%;"></el-input>
          </el-form-item>

          <!-- 答案解析 富文本编辑器-->
          <el-form-item :label="$t('question.answer') + ':'" prop="answer">
            <quill-editor
              v-model="pubForm.answer"
              class="richText"
              ref="quillEditorAnswer"
              @change="answerQuillChange"
              :options="quillOptionAnswer"
            ></quill-editor>
          </el-form-item>
          <!-- 富文本编辑器图片上传组件，隐藏 -->
          <el-upload
            action="#"
            id="uploaderAnswer"
            v-show="false"
            :http-request="uploadAnswer"
            :before-upload="beforeAvatarUpload"
          >
          </el-upload>
          <!-- 题目备注 -->
          <el-form-item :label="$t('question.remarks') + ':'">
            <el-input
              type="textarea"
              :rows="5"
              v-model="pubForm.remarks"
              style="width: 50%;height:100%"
            ></el-input>
          </el-form-item>

          <!-- 试题标签 -->
          <el-form-item :label="$t('question.tags') + ':'" prop="tags">
            <el-select
              v-model="pubForm.tags"
              multiple
              filterable
              allow-create
              default-first-option
              style="width: 50%;"
            >
              <el-option
                v-for="item in tagList"
                :key="item.id"
                :label="item.tagName"
                :value="item.tagName"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item>
            <!-- 修改按钮 -->
            <el-button v-if="$route.query.id" type="success" @click="submit">{{
              $t("form.edit")
            }}</el-button>
            <!-- 添加按钮 -->
            <el-button v-else type="primary" @click="submit">{{
              $t("form.submit")
            }}</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
  </div>
</template>

<script>
// 引入数据请求函数
import { list as subjectList } from "@/api/hmmm/subjects";
import { list as catalogList } from "@/api/hmmm/directorys";
import { list as companyList } from "@/api/hmmm/companys";
import { list as tagList } from "@/api/hmmm/tags";
import { provinces, citys } from "@/api/hmmm/citys";
import { direction } from "@/api/hmmm/constants";
import { add, update } from "@/api/hmmm/questions";
import { detail } from "@/api/hmmm/questions";
// 引入代码高亮
import hljs from "highlight.js";
import "highlight.js/styles/monokai-sublime.css";
// 引入富文本编辑器组件和样式
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { quillEditor } from "vue-quill-editor";
// 引入腾讯云COS，并创建实例
const COS = require("cos-js-sdk-v5");
const cos = new COS({
  SecretId: "AKIDSjlW0D9xZuxkJcdOs50f3AzXooXzA5j6", // 身份识别ID
  SecretKey: "8zZrsc5HCrEK9hz0kDPKzNVLuCDxPbWA" // 身份秘钥
});
export default {
  name: "questions-new",
  components: { quillEditor },
  data() {
    // 富文本编辑器工具栏配置
    const toolbarOptions = [
      ["bold", "italic", "underline", "strike"],
      [{ list: "ordered" }, { list: "bullet" }],
      ["blockquote"],
      ["code-block", "image", "link"]
    ];
    // 富文本编辑器图片上传自定义(题干和答案各一个)
    const imageHandlerQuestion = function(value) {
      if (value) {
        // 调用自定义图片上传
        document.querySelector("#uploaderQuestion .el-upload").click();
      } else {
        this.quill.format("image", false);
      }
    };
    const imageHandlerAnswer = function(value) {
      if (value) {
        // 调用自定义图片上传
        document.querySelector("#uploaderAnswer .el-upload").click();
      } else {
        this.quill.format("image", false);
      }
    };
    return {
      pubForm: {
        subjectID: "", //学科
        catalogID: "", //目录
        enterpriseID: "", //企业
        province: "", //省份
        city: "", //城市
        direction: "", //方向
        questionType: "1", //题型
        difficulty: "1", //难度
        question: "", //题干
        videoURL: "", //答案解析视频url
        answer: "", //答案
        remarks: "", //备注
        tags: [], //标签
        options: [
          { code: "A", title: "", img: "", isRight: false },
          { code: "B", title: "", img: "", isRight: false },
          { code: "C", title: "", img: "", isRight: false },
          { code: "D", title: "", img: "", isRight: false }
        ] //选项详情：code代号,title选项文字内容,img选项图片,isRight是否为正确答案
      },
      pubRules: {
        subjectID: [{ required: true, message: "请选择学科" }],
        catalogID: [{ required: true, message: "请选择目录" }],
        enterpriseID: [{ required: true, message: "请选择企业" }],
        city: [{ required: true, message: "请选择地区" }],
        direction: [{ required: true, message: "请选择方向" }],
        questionType: [{ required: true, message: "请选择题型" }],
        difficulty: [{ required: true, message: "请选择难度" }],
        question: [{ required: true, message: "请输入题干" }],
        answer: [{ required: true, message: "请输入答案解析" }]
      },
      subjectList: [], // 学科列表
      catalogList: [], // 目录列表
      companyList: [], // 企业列表
      provinceList: [], // 省份列表
      regionList: [], // 区域列表
      directionList: [], // 方向列表
      tagList: [], // 标签列表
      radio: "A", // 单选框选中选项
      checkList: ["A", "B"], // 多选框选中选项数组,至少选择两项
      key: 0, // 用于配合key属性手动重新渲染元素
      //题干富文本编辑器配置
      quillOptionQuestion: {
        // placeholder: this.$t("form.input"),
        modules: {
          // 配置工具栏
          toolbar: {
            container: toolbarOptions,
            // 自定义图片上传行为
            handlers: {
              image: imageHandlerQuestion
            }
          },
          // 配置代码高亮
          syntax: {
            highlight: text => hljs.highlightAuto(text).value
          }
        }
      },
      //答案富文本编辑器配置
      quillOptionAnswer: {
        // placeholder: this.$t("form.input"),
        modules: {
          // 配置工具栏
          toolbar: {
            container: toolbarOptions,
            // 自定义图片上传行为
            handlers: {
              image: imageHandlerAnswer
            }
          },
          // 配置代码高亮
          syntax: {
            highlight: text => hljs.highlightAuto(text).value
          }
        }
      }
    };
  },
  // 从编辑页面跳转新增页面时，组件复用，需手动重置数据
  beforeRouteUpdate(to, from, next) {
    Object.assign(this.$data.pubForm, this.$options.data().pubForm);
    //表单元素key值改变，重新渲染，避免表单验证
    this.key += 1;
    next();
  },
  created() {
    // 初始化学科、企业、省份、方向列表
    this.getSubjectList();
    this.getCompanyList();
    this.provinceList = provinces();
    this.directionList = direction;
    // 如果是修改，初始化表单数据
    if (this.$route.query.id) {
      detail({ id: this.$route.query.id })
        .then(({ data: res }) => {
          console.log(res);
          // 答案按code顺序排列
          this.sortOptions(res.options);
          // 获取正确答案
          this.getRightChoice(res.options);
          this.pubForm = res;
          // 标签由字符串转数组
          this.pubForm.tags = res.tags.split(" ");
          // 页面渲染完毕后回到顶部
          this.$nextTick(() => {
            document.querySelector("#anchor").scrollIntoView();
          });
        })
        .catch(e => {
          console.log(e);
        });
    }
  },
  methods: {
    // 用于数据回填时计算正确选项的函数
    getRightChoice(options) {
      const rightList = [];
      options.forEach(item => {
        if (item.isRight) rightList.push(item.code);
      });
      // 正确选项大于1个为多选题
      if (rightList.length > 1) {
        this.checkList = rightList;
      } else {
        this.radio = rightList[0];
      }
    },
    // 用于数据回填时按顺序排列答案选项
    sortOptions(options) {
      options.sort((a, b) => {
        return a.code < b.code ? -1 : 1;
      });
    },
    // 获取全部学科列表
    async getSubjectList() {
      try {
        const { data } = await subjectList({ pagesize: 100 });
        this.subjectList = data.items;
      } catch (err) {
        this.$message.error("获取学科列表失败");
      }
    },
    // 获取全部企业列表
    async getCompanyList() {
      try {
        const { data } = await companyList({ pagesize: 100 });
        this.companyList = data.items;
        this.isLoading = false;
      } catch (err) {
        this.$message.error("获取企业列表失败");
      }
    },
    // 根据学科id获取目录列表
    async getCatalogList(subjectID) {
      // 清空当前目录列表
      this.catalogList = [];
      // 清除当前选择的目录
      this.catalogID = "";
      try {
        const { data } = await catalogList({ subjectID });
        this.catalogList = data.items;
      } catch (err) {
        this.$message.error("获取目录列表失败");
      }
    },

    // 根据学科id获取标签列表
    async getTagList(subjectID) {
      // 清空当前目录列表
      this.tagList = [];
      // 清除当前选择的标签
      this.tags = "";
      try {
        const { data } = await tagList({ subjectID });
        this.tagList = data.items;
      } catch (err) {
        this.$message.error("获取标签列表失败");
      }
    },
    // 学科下拉框选择改变时，获取对应的目录和标签列表
    subjectChange(subjectID) {
      this.getCatalogList(subjectID);
      this.getTagList(subjectID);
    },
    // 省份下拉框发生改变时获取对应的区域信息
    provinceChange(data) {
      this.pubForm.city = "";
      this.regionList = citys(data);
    },
    // 单选按钮组选择变化事件
    radioChange() {
      this.pubForm.options.forEach(item => {
        item.isRight = item.code === this.radio ? true : false;
      });
    },
    // 多选按钮组选择变化事件
    checkboxChange() {
      this.pubForm.options.forEach(item => {
        item.isRight = this.checkList.includes(item.code) ? true : false;
      });
    },
    // 增加选项操作
    addOption() {
      // 获取当前最后一个选项的code值
      const curCode = this.pubForm.options[this.pubForm.options.length - 1]
        .code;
      // 计算字母表中下一个字母
      const nextCode = String.fromCodePoint(curCode.codePointAt(0) + 1);
      this.pubForm.options.push({
        code: nextCode,
        title: "",
        img: "",
        isRight: false
      });
    },
    //题型改变时，删除答案选项数组多余项（保证单选只有4项）
    questionTypeChange() {
      this.pubForm.options.splice(4);
    },
    // 题干富文本编辑器内容改变触发验证
    questionQuillChange() {
      this.$refs.pubRef.validateField("question");
    },
    // 答案富文本编辑器内容改变触发验证
    answerQuillChange() {
      this.$refs.pubRef.validateField("answer");
    },
    // 表单提交
    submit() {
      this.$refs.pubRef.validate(async valid => {
        if (valid) {
          // this.loading = true;
          this.$route.query.id
            ? await update({
                ...this.pubForm,
                // 标签数组转换为以空格分隔的字符串
                tags: this.pubForm.tags.join(" ")
              })
            : await add({
                ...this.pubForm,
                // 标签数组转换为以空格分隔的字符串
                tags: this.pubForm.tags.join(" ")
              });
          this.$message.success(this.$route.query.id ? "修改成功" : "新增成功");
          // 重置表单
          this.$refs.pubRef.resetFields();
          // 跳转基础列表页面
          this.$router.push("/questions/list");
          // this.loading = false;
        } else {
          console.log("表单验证失败");
        }
      });
    },
    handleAvatarSuccess(res, file) {
      // this.imageUrl = URL.createObjectURL(file.raw);
      console.log("图片上传未完成");
    },
    // 题干文件上传函数
    uploadQuestion(res) {
      this.upload(res, "quillEditorQuestion");
    },
    // 答案文件上传函数
    uploadAnswer(res) {
      this.upload(res, "quillEditorAnswer");
    },
    // 文件上传函数
    upload(res, quillEditorName) {
      if (res.file) {
        // 上传状态改变
        this.isUploading = true;
        // 上传腾讯云
        cos.putObject(
          {
            Bucket: "psrj07373039-1312444976" /* 必须 */,
            Region: "ap-beijing" /* 存储桶所在地域，必须字段 */,
            Key: res.file.name /* 必须 */,
            StorageClass: "STANDARD",
            Body: res.file, // 上传文件对象
            onProgress: progressData => {
              console.log(JSON.stringify(progressData));
            }
          },
          (err, data) => {
            console.log(err || data);
            // 上传成功后相应处理
            if (data.statusCode === 200) {
              // 获取富文本组件实例
              const quill = this.$refs[quillEditorName].quill;
              // 获取光标所在位置
              const length = quill.getSelection().index;
              // 插入图片
              quill.insertEmbed(length, "image", `https:${data.Location}`);
              // 调整光标到最后
              quill.setSelection(length + 1);
            } else {
              this.$message.error("图片上传失败");
            }
          }
        );
      }
    },
    // 文件上传前处理函数
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    }
  }
};
</script>

<style scoped lang="scss">
.erect {
  position: relative;
  width: 400px;
  margin-top: 20px;
  margin-bottom: 50px;
}
.erectInput {
  width: 240px;
}
::v-deep.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: absolute;
  height: 60px;
  width: 100px;
  margin-top: -50px;
  margin-left: 315px;
}
.upload-icon {
  line-height: 60px;
  font-size: 15px !important;
  font-style: inherit;
}
.el-icon-circle-close {
  position: absolute;
  top: -8px;
  right: -7px;
  color: #a8a1a1;
  font-size: 19px;
}
.erectButton {
  position: absolute;
  bottom: 0;
  left: 0;
  color: #fff;
}
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 60px;
  line-height: 60px;
  text-align: center;
}
.avatar {
  width: 100px;
  height: 60px;
  display: block;
}
// 富文本编辑器样式
.richText {
  margin-bottom: 30px;
  width: 70%;
  ::v-deep .ql-container {
    min-height: 200px;
    max-height: 300px;
    overflow: auto;
  }
}
.dashboard-container {
  position: relative;
  #anchor {
    position: absolute;
    top: -110px;
    left: 50%;
    width: 10px;
    height: 10px;
  }
}
</style>
